﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using ExcelRefresh.Com;
using Microsoft.Office.Interop.Excel;

namespace ExcelRefresh.Excel
{
    public abstract class ExcelUtilities : ComHelpers
    {
        public static bool IsFileLocked( FileInfo file)
        {
            try
            {
                using (var stream = file.OpenWrite())
                    return false;
            }
            catch (IOException)
            {
                return true;
            }
        }

        public static bool IsFileLocked(string path)
        {
            return IsFileLocked(new FileInfo(path));
        }

        public static void RefreshWorkbook(string sourcePath, string saveToPath, string backupPath)
        {
            if (IsFileLocked(sourcePath))
                throw new FileInUseException("Cannot open " + sourcePath + " for writing. File is in use.");

            var startTime = DateTime.Now;

            UsingWorkbook
            (
                sourcePath, 
                book =>
                {
                    Trace.TraceInformation("Refreshing {0}", book.Name);
                    RefreshAll(book);
                    Trace.TraceInformation("Refreshed {1}  - Duration: {0}", DateTime.Now - startTime, book.Name);
                    book.Comments = string.Format("Refreshed: {1:dd MMM, HH\\:mm}  Duration: {0:mm\\:ss}", DateTime.Now - startTime, DateTime.Now);
        
                    if (sourcePath == saveToPath)
                        book.Save();
                    else
                        book.SaveCopyAs(saveToPath);

                    if (!string.IsNullOrEmpty(backupPath))
                    {
                        var folder = Path.GetDirectoryName(backupPath);
                        
                        if (!Directory.Exists(folder))
                            Directory.CreateDirectory(folder);

                        var statusProp = book.BuiltinDocumentProperties["Content Status"];
                        statusProp.Value = "Archive";
                        book.SaveCopyAs(backupPath);
                    }
                }
        );
        }


        public static void RefreshAll(Workbook workbook)
        {
            var restoreActions = new List<System.Action>();

            foreach (WorkbookConnection connection in workbook.Connections)
            {
                switch (connection.Type)
                {
                    case XlConnectionType.xlConnectionTypeOLEDB:
                        if (connection.Name == "ThisWorkbookDataModel") break;
                        if (connection.OLEDBConnection.BackgroundQuery)
                            restoreActions.Add(() => connection.OLEDBConnection.BackgroundQuery = true);
                        connection.OLEDBConnection.BackgroundQuery = false;
                        break;

                    case XlConnectionType.xlConnectionTypeODBC:
                        if (connection.ODBCConnection.BackgroundQuery)
                            restoreActions.Add(() => connection.ODBCConnection.BackgroundQuery = true);
                        connection.ODBCConnection.BackgroundQuery = false;
                        break;
                }
            } 
            
            workbook.RefreshAll();

            foreach (var action in restoreActions)
                action();
        }
    }
}
